<!--
 * @Descripttion: 
 * @version: 
 * @Author: wjh
 * @Date: 2022-02-20 15:03:39
 * @LastEditors: wjh
 * @LastEditTime: 2022-03-13 21:07:33
-->
<template>
  <!-- 输入框 -->
  <el-input
    v-if="item.type === 'input'"
    v-model="data"
    v-bind="getBind(item)"
    v-on="getOn(item)"
  />

  <!-- 数字 -->
  <el-input-number
    v-else-if="item.type === 'number'"
    v-model="data"
    v-bind="getBind(item)"
    v-on="getOn(item)"
  />

  <!-- 时间选择器 -->
  <el-date-picker
    v-else-if="item.type == 'time'"
    v-model="data"
    v-bind="getBind(item)"
    v-on="getOn(item)"
  />

  <!-- 选择框  -->
  <el-select
    v-else-if="item.type === 'select'"
    v-model="data"
    v-bind="getBind(item)"
    v-on="getOn(item)"
  >
    <el-option
      v-for="(it, index) in getList(item)"
      :key="index"
      v-bind="getOptionBind(item, it)"
    >
    </el-option>
  </el-select>

  <!-- 多选框 -->
  <el-checkbox-group  
    v-else-if="item.type === 'checkbox'"
    v-model="data" 
    v-bind="getBind(item)"
    v-on="getOn(item)">
    <el-checkbox 
      v-for="(it, index) in getList(item)" 
      :key="index"
      :label="getOptionBind(item, it).value">
      {{getOptionBind(item, it).label}}
    </el-checkbox>
  </el-checkbox-group>
  
  <!-- 开关 -->
  <el-switch
    v-else-if="item.type === 'switch'"
    v-model="data"
    v-bind="getBind(item)"
    v-on="getOn(item)"
  />

  <!-- 按钮组  -->
  <div v-else-if="item.type === 'btn'">
    <el-button
      v-for="(it, index) in getList(item)"
      :key="index"
      v-bind="getBtnBind(it)"
      v-on="getBtnOn(it)"
    >
      {{ it.text }}
    </el-button>
  </div>

  <!-- 文本 -->
  <div
    v-else-if="item.type === 'text'"
    v-bind="getBind(item)"
    v-on="getOn(item)"
  >
    {{ item.getText ? item.getText(data) : data }}
  </div>

  <!-- 树级选择器 -->
  <el-select
    v-else-if="item.type === 'select-tree'"
    v-model="data"
    v-bind="getBind(item)"
    v-on="getOn(item)"
  >
    <el-tree :data="getList(item)" v-bind="getTreeBind(item)">
      <template #default="{ data }">
        <el-option v-bind="getOptionBind(item, data)" />
      </template>
    </el-tree>
  </el-select>

  <el-cascader
    v-else-if="item.type === 'cascader'"
    v-model="data"
    v-bind="getBind(item)"
    v-on="getOn(item)"
  ></el-cascader>

  <!-- 文件上传 -->
  <el-upload
    v-else-if="item.type === 'upload-picture'"
    v-bind="getBind(item)"
    v-on="getOn(item)"
  >
    <i class="el-icon-plus"></i>
  </el-upload>

  <el-image
    v-else-if="item.type === 'picture'"
    :src="data ? data : ''"
    v-bind="getBind(item)"
    v-on="getOn(item)"
  />

  <!-- 单选框 -->
  <el-radio-group
    v-else-if="item.type === 'radio'"
    v-model="data"
    v-bind="getBind(item)"
    v-on="getOn(item)"
  >
    <el-radio
      v-for="(it, i) in item.list"
      :key="i"
      v-bind="getRadioBind(item, it)"
    >
      {{ getRadioText(item, it) }}
    </el-radio>
  </el-radio-group>

  <component
    v-else
    :is="item.type"
    v-model="data"
    v-bind="getBind(item)"
    v-on="getOn(item)"
  />
</template>

<script>
import * as _ from "lodash";
let isObject = (data) =>Object.prototype.toString.call(data) === "[object Object]";//判断是否为对象
let isFunction = (data) =>Object.prototype.toString.call(data) === "[object Function]";//判断是否为方法
export default {
  props: {
    item: Object,
    row: Object,
    value: [String, Object, Number, Boolean, Array],
  },
  computed: {
    data: {
      get() {
        return this.value;
      },
      set(val) {
        this.$emit("input", val);
      },
    },
  },
  data() {
    let _this = this;
    return {
      visible: false,
      popoverSelectValue: null,
      getDefBind(item) {
        return (
          {
            input: {
              placeholder: "请输入" + item.label,
            },
            time: {
              placeholder: "请选择" + item.label,
              valueFormat: "yyyy-MM-dd HH:mm:ss",
              type: "datetime",
            },
            number: {
              placeholder: "请输入" + item.label,
            },
            select: {
              placeholder: "请选择" + item.label,
            },
            radio: {},
            "select-tree": {
              placeholder: "请选择" + item.label,
            },
            checkbox: {},
            switch: {
              activeValue: true,
              inactiveValue: false,
              activeText: "是",
              inactiveText: "否",
            },
          }[item.type] || {}
        );
      },
      getDefOptionBind: (val) => ({ label: val, value: val }),
      getDefTreeBind(item) {
        return {};
      },
    };
  },

  methods: {
    getTreeBind(item) {
      let defBind = this.getDefTreeBind(item),
        attrs = isObject(item?.treeBind) ? item.treeBind : {};
      return _.merge(defBind, attrs);
    },
    getTreeOn(item) {
      return isObject(item.treeOn)
        ? item.treeOn
        : isFunction(item.treeOn)
        ? item.treeOn(this.value, item, this.row)
        : {};
    },
    getList(item) {
      let list = Array.isArray(item?.list)
        ? item.list
        : isFunction(item?.list)
        ? item.list(this.value, item, this.row)
        : [];
      return list;
    },
    // 下面两个方法是radio的配置
    getRadioBind(item, val){
      let optionBind = item?.optionBind

      let bind = isObject(optionBind)
          ? { label: val[optionBind.value]}
          : { label: val};
      return bind;
    },
    getRadioText(item, val){
      let optionBind = item?.optionBind

      let bind = isObject(optionBind)
          ? val[optionBind.label]
          : val
      return bind;
    },

    getOptionBind(item, val) {
      let optionBind = item?.optionBind

      let bind = isFunction(optionBind)
        ? optionBind(val)
        : isObject(optionBind)
          ? { 
              label: optionBind.label ? val[optionBind.label] : val, 
              value: optionBind.value ? val[optionBind.value] : val 
            }
          : { label: val, value: val };
      return bind;
    },
    getBtnBind(it) {
      let bind = isObject(it?.bind) ? it.bind : {};
      return bind;
    },
    getBtnOn(it) {
      let listeners = isObject(it?.on)
        ? it.on
        : isFunction(it.on)
        ? it.on(this.row)
        : {};
      return listeners;
    },
    getBind(item) {
      let defBind = this.getDefBind(item),
        attrs = isObject(item.bind)
          ? item.bind
          : isFunction(item.bind)
          ? item.bind(this.value, item, this.row)
          : {};
      return _.merge(defBind, attrs);
    },
    getOn(item) {
      return isObject(item.on)
        ? item.on
        : isFunction(item.on)
        ? item.on(this.value, item, this.row)
        : {};
    },
  },
};
</script>

<style lang="scss">
.popper-class-abnormal {
  display: none;
}
.popover-select {
  text-align: right;
  .top {
    display: flex;
    margin-bottom: 10px;
    .el-tree {
      min-width: 200px;
    }
  }
}
</style>
